﻿using System;
using System.Linq;

namespace Borg
{
    public static class ArrayEx
    {
        internal static T[] Add<T>(T[] oldElements, T element)
        {
            if (oldElements == null)
                return new[] {element};
            
            var items = new T[oldElements.Length + 1];

            Array.Copy(oldElements, 0, items, 0, oldElements.Length);
            items[oldElements.Length] = element;

            return items;
        }

        public static T[] Insert<T>(T[] oldElements, int index, T element)
        {
            if (oldElements == null)
                return new[] {element};
            
            var items = new T[oldElements.Length + 1];

            if (index == 0)
            {
                items[0] = element;
                Array.Copy(oldElements, 0, items, 1, oldElements.Length);
            }
            else
            {
                Array.Copy(oldElements, 0, items, 0, index);
                items[index] = element;
                Array.Copy(oldElements, index, items, index + 1, oldElements.Length - index);
            }

            return items;
        }

        public static T[] Remove<T>(T[] oldElements, T element)
        {
            if (oldElements == null)
                return null;

            if (oldElements.Length == 1)
                return
                    oldElements[0].Equals(element)
                        ? null
                        : oldElements;
            
            var index = Array.IndexOf(oldElements, element, 0, oldElements.Length);

            return
                index < 0
                    ? oldElements
                    : RemoveAt(oldElements, index);
        }

        public static T[] RemoveAt<T>(T[] oldElements, int index)
        {
            var items = new T[oldElements.Length - 1];

            Array.Copy(oldElements, 0, items, 0, index);
            Array.Copy(oldElements, index + 1, items, index, items.Length - index);

            return items;
        }

        public static bool Contains<T>(T[] elements, T element)
        {
            return elements.Any(obj => obj.Equals(element));
        }
    }
}
